﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace CNKI.TPI.Web.Base.HtmlHelp
{
    /// <summary>
    /// input 标签扩展类
    /// </summary>
    public static class ListControlExtensions
    {
        /// <summary>
        /// RadioButtionList 用法参考/CNet/Channel/ModyOp
        /// </summary>
        /// <param name="TEnum">枚举类型</param>
        /// <param name="selectInt">当前选择如果不设置则为null</param>
        /// <returns></returns>
        public static MvcHtmlString RadioButtonListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type TEnum, int? selectInt)
        {
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
            string name = ExpressionHelper.GetExpressionText(expression);
            string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
            return ListControlUtil.GenerateHtml(TEnum, fullHtmlFieldName, metadata.Model, "radio", selectInt);
        }
        public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type TEnum, IEnumerable<int> selectInt)
        {
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
            string name = ExpressionHelper.GetExpressionText(expression);
            string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
            return ListControlUtil.GenerateHtml(TEnum, fullHtmlFieldName, metadata.Model, "checkbox", selectInt);
        }
        /// <summary>
        /// 例子    @(Html.RadioButtonListEnum<Edu.Model.Enum.EnumColumnType>("ColumnType")) 
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="name"></param>
        /// <param name="select">引用时需判断对象是否为null</param>
        /// <returns></returns>
        public static MvcHtmlString RadioButtonListEnum<TEnum>(this HtmlHelper htmlHelper, string name, int? selectInt)
        {
            IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum))
                .Cast<TEnum>();
            StringBuilder sb = new StringBuilder();
            int i = 0;
            foreach (var value in values)
            {
                i++;
                bool isChecked = false;
                if (selectInt != null)
                {
                    isChecked = Convert.ToInt32(value) == selectInt;
                }
                string id = string.Format("{0}_{1}", name, i);
                sb.Append(ListControlUtil.GenerateRadioHtml(name, id, EnumDescription.GetFieldText(value), Convert.ToInt32(value).ToString(), isChecked, "radio"));
            }
            return new MvcHtmlString(sb.ToString());
        }
        /// <summary>
        /// CheckBoxListEnum
        /// </summary>
        /// <typeparam name="TEnum">枚举</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="name">实体对象名称</param>
        /// <param name="selectInt">如果默认没有为null</param>
        /// <returns></returns>
        public static MvcHtmlString CheckBoxListEnum<TEnum>(this HtmlHelper htmlHelper, string name, IEnumerable<int> selectInt)
        {
            IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum))
                .Cast<TEnum>();
            StringBuilder sb = new StringBuilder();
            int i = 0;
            foreach (var value in values)
            {
                i++;
                bool isChecked = false;
                if (selectInt != null)
                {
                    isChecked = selectInt.Contains(Convert.ToInt32(value));
                }
                string id = string.Format("{0}_{1}", name, i);
                sb.Append(ListControlUtil.GenerateRadioHtml(name, id, EnumDescription.GetFieldText(value), Convert.ToInt32(value).ToString(), isChecked, "radio"));
            }
            return new MvcHtmlString(sb.ToString());
        }
    }

    public static class ListControlUtil
    {
        public static MvcHtmlString GenerateHtml(Type TEnum, string name, object stateValue, string type, object selectInt)
        {
            int i = 0;
            StringBuilder sb = new StringBuilder();
            Array values = Enum.GetValues(TEnum);

            foreach (var value in values)
            {
                i++;
                string id = string.Format("{0}_{1}", name, i);
                bool isChecked = false;
                if (stateValue == null)
                {
                    if (selectInt != null)
                    {
                        if (type == "radio")
                        {
                            isChecked = Convert.ToInt32(value) == Convert.ToInt32(selectInt);
                        }
                        else
                        {
                            IEnumerable<int> currentValues = selectInt as IEnumerable<int>;
                            isChecked = currentValues.Contains(Convert.ToInt32(value));
                        }
                    }
                }
                else
                {

                    isChecked = (null != stateValue && Convert.ToInt32(value).ToString() == stateValue.ToString());
                }
                string st = GenerateRadioHtml(name, id, EnumDescription.GetFieldText(value), Convert.ToInt32(value).ToString(), isChecked, type);
                sb.Append(st);
            }
            return new MvcHtmlString(sb.ToString());
        }

        public static string GenerateRadioHtml(string name, string id, string labelText, string value, bool isChecked, string type)
        {
            StringBuilder sb = new StringBuilder();

            System.Web.Mvc.TagBuilder label = new TagBuilder("label");
            label.MergeAttribute("for", id);
            label.MergeAttribute("class", "lblfor");
            label.SetInnerText(labelText);

            TagBuilder input = new TagBuilder("input");
            input.GenerateId(id);
            input.MergeAttribute("name", name);

            input.MergeAttribute("type", type);
            input.MergeAttribute("value", value);
            if (isChecked)
            {
                input.MergeAttribute("checked", "checked");
            }
            sb.AppendLine(input.ToString());
            sb.AppendLine(label.ToString());
            return sb.ToString();
        }
    }
}